﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GenericStateMachine
{
    /// <summary>
    /// Represents a state of state machine.
    /// </summary>
    /// <typeparam name="TStateContext">The type of state context interface.</typeparam>
    /// <typeparam name="TState">The type of state interface.</typeparam>
    /// <typeparam name="TStateType">The type of concrete state enumeration.</typeparam>
    public interface IState<TStateContext, TState, TStateType>
        where TStateContext : IStateContext<TStateContext, TState, TStateType>
        where TState : IState<TStateContext, TState, TStateType>
        where TStateType : struct, IComparable, IFormattable, IConvertible
    {
        /// <summary>
        /// Gets the state context.
        /// </summary>
        TStateContext Context { get; }

        /// <summary>
        /// Gets the value indicating concrete state type.
        /// </summary>
        TStateType StateType { get; }

        /// <summary>
        /// Invoked when entering the state except for initial state.
        /// </summary>
        /// <returns>The next state type.</returns>
        TStateType OnEntry();

        /// <summary>
        /// Invoked when exiting the state.
        /// </summary>
        void OnExit();
    }

    // internal interface
    internal interface IStateEx
    {
        void SetContext(object context);
    }
}
